//+------------------------------------------------------------------+
//|                                           RSI_Martingale_EA.mq5 |
//|                                   基于RSI的马丁格尔交易策略EA    |
//|                                        Copyright 2024, 量化专家 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, 量化专家"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property description "基于RSI突破的马丁格尔策略EA"

#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>

//--- 输入参数
input group "=== RSI参数 ==="
input int                InpRSI_Period = 14;                   // RSI周期
input double             InpRSI_Lower = 30.0;                  // RSI买入判定阈值
input double             InpRSI_Upper = 70.0;                  // RSI卖出判定阈值
input bool               InpUse_RSI_Trend = false;             // 启用RSI趋势判定
input group "=== KDJ参数 ==="
input int                InpKDJ_K_Period = 9;                  // K值周期
input int                InpKDJ_D_Period = 3;                  // D值周期
input int                InpKDJ_Slowing = 3;                   // 平滑参数

input group "=== 马丁格尔参数 ==="
input double             InpStart_Lot = 0.1;                   // 起始手数
input double             InpLot_Multiplier = 1.5;              // 手数倍数
input int                InpMax_Orders = 5;                    // 最大订单数

input group "=== ATR参数 ==="
input int                InpATR_Period = 14;                   // ATR周期
input double             InpATR_Distance = 1.0;                // ATR加仓间距倍数
input double             InpATR_TP_Multi = 3.0;                // ATR止盈倍数
input double             InpATR_SL_Multi = 4.0;                // ATR止损倍数(第5单后)

input group "=== 风险管理 ==="
input double             InpMax_Loss = 500.0;                  // 最大亏损金额
input bool               InpUse_RSI_Exit = false;              // 启用RSI出场
input bool               InpUse_Trailing_Stop = true;          // 启用移动止损
input double             InpTrail_Start_ATR = 2.0;             // 移动止损启动倍数(ATR)
input double             InpTrail_Distance_ATR = 1.0;          // 移动止损距离(ATR)
input double             InpTrail_Step_ATR = 0.1;              // 移动止损最小步长(ATR)

input group "=== 其他设置 ==="
input int                InpMagic_Number = 123456;             // 魔术号
input string             InpComment = "RSI_Martingale";        // 订单注释
input int                InpSignal_Valid_Bars = 3;             // 信号有效K线数(3-5)
input bool               InpShow_Chart_Labels = true;          // 显示图表标签

//--- 全局变量
CTrade         m_trade;
CPositionInfo  m_position;

int            h_RSI;                 // RSI句柄
int            h_ATR;                 // ATR句柄
int            h_Stochastic;          // KDJ句柄

// 交易状态变量
struct TradingState
{
    int order_count;                  // 当前订单数量
    double last_buy_price;            // 最后买入价格
    double last_sell_price;           // 最后卖出价格
    double lowest_buy_price;          // 最低买入价格
    double highest_sell_price;        // 最高卖出价格
    double avg_buy_price;             // 买入均价
    double avg_sell_price;            // 卖出均价
    double total_buy_lots;            // 总买入手数
    double total_sell_lots;           // 总卖出手数
    bool has_buy_positions;           // 是否有买单
    bool has_sell_positions;          // 是否有卖单
    datetime last_trade_time;         // 最后交易时间
    

    
    // 移动止损
    double trailing_stop_buy;         // 多头移动止损价
    double trailing_stop_sell;        // 空头移动止损价
    bool trailing_active_buy;         // 多头移动止损是否激活
    bool trailing_active_sell;        // 空头移动止损是否激活
};

TradingState g_state;

// RSI状态跟踪
double g_prev_rsi = 50.0;
double g_curr_rsi = 50.0;

// KDJ状态跟踪
double g_prev_k = 50.0;
double g_curr_k = 50.0;
double g_prev_d = 50.0;
double g_curr_d = 50.0;

// 调试计数器
int debug_counter = 0;

// 新增：开仓条件缓存结构
struct SignalCache
{
    // RSI信号
    bool rsi_buy_rise;               // RSI买入回升信号（从30以下回升到30以上）
    bool rsi_sell_fallback;          // RSI卖出回落信号（从70以上回落到70以下）
    datetime rsi_buy_expire_time;    // RSI买入信号过期时间
    datetime rsi_sell_expire_time;   // RSI卖出信号过期时间
    
    // KDJ交叉信号
    bool kdj_golden_cross;           // KDJ金叉信号（K上穿D，K<20时）
    bool kdj_death_cross;            // KDJ死叉信号（K下穿D，K>80时）
    datetime kdj_golden_expire_time; // KDJ金叉信号过期时间
    datetime kdj_death_expire_time;  // KDJ死叉信号过期时间
    datetime kdj_golden_last_update; // 上次更新金叉的时间（避免1分钟内重复更新）
    datetime kdj_death_last_update;  // 上次更新死叉的时间（避免1分钟内重复更新）
    
    // KDJ纠缠检测
    bool kdj_low_entangle;           // KDJ低位纠缠状态
    bool kdj_high_entangle;          // KDJ高位纠缠状态
    int kdj_low_entangle_ticks;      // 低位纠缠持续tick数
    int kdj_high_entangle_ticks;     // 高位纠缠持续tick数
    datetime kdj_low_entangle_start; // 低位纠缠开始时间
    datetime kdj_high_entangle_start; // 高位纠缠开始时间
    
    // 配置参数
    int signal_valid_bars;           // 信号有效K线数
};

SignalCache g_signal_cache;

//+------------------------------------------------------------------+
//| 专家初始化函数                                                   |
//+------------------------------------------------------------------+
int OnInit()
{
    // 设置交易类
    m_trade.SetExpertMagicNumber(InpMagic_Number);
    m_trade.SetDeviationInPoints(10);
    
    // 创建RSI指标
    h_RSI = iRSI(_Symbol, PERIOD_CURRENT, InpRSI_Period, PRICE_CLOSE);
    if(h_RSI == INVALID_HANDLE)
    {
        Print("创建RSI指标失败，错误码：", GetLastError());
        return INIT_FAILED;
    }
    
    // 创建ATR指标
    h_ATR = iATR(_Symbol, PERIOD_CURRENT, InpATR_Period);
    if(h_ATR == INVALID_HANDLE)
    {
        Print("创建ATR指标失败，错误码：", GetLastError());
        return INIT_FAILED;
    }
    
    // 创建KDJ指标
    h_Stochastic = iStochastic(_Symbol, PERIOD_CURRENT, InpKDJ_K_Period, InpKDJ_D_Period, InpKDJ_Slowing, MODE_SMA, STO_LOWHIGH);
    if(h_Stochastic == INVALID_HANDLE)
    {
        Print("创建KDJ指标失败，错误码：", GetLastError());
        return INIT_FAILED;
    }
    
    // 初始化交易状态
    InitTradingState();
    
    // 初始化信号缓存
    InitSignalCache();
    
    // 输出品种交易规格
    double min_lot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
    double max_lot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
    double lot_step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
    
    Print("📋 品种交易规格：");
    Print("   最小手数：", min_lot);
    Print("   最大手数：", max_lot);
    Print("   手数步长：", lot_step);
    Print("   起始手数（规范化前）：", InpStart_Lot);
    Print("   起始手数（规范化后）：", NormalizeLot(InpStart_Lot));
    
    Print("✅ RSI马丁格尔EA初始化成功");
    return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
//| 专家去初始化函数                                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    if(h_RSI != INVALID_HANDLE) IndicatorRelease(h_RSI);
    if(h_ATR != INVALID_HANDLE) IndicatorRelease(h_ATR);
    if(h_Stochastic != INVALID_HANDLE) IndicatorRelease(h_Stochastic);
    Print("EA已卸载，原因代码：", reason);
}

//+------------------------------------------------------------------+
//| 主要执行函数                                                     |
//+------------------------------------------------------------------+
void OnTick()
{
    // 增加调试计数器
    debug_counter++;
    
    // 更新交易状态
    UpdateTradingState();
    
    // 更新RSI值
    UpdateRSIValues();

    // 更新KDJ值
    UpdateKDJValues();
    
    // 每个tick都检测RSI信号
    CheckRSISignalOnTick();
    
    // 每个tick都检测KDJ金叉死叉信号
    CheckKDJCrossSignalOnTick();
    
    // 每分钟更新一次图表标签
    static datetime last_label_update = 0;
    datetime current_minute = TimeCurrent() - (TimeCurrent() % 60); // 取整到分钟
    
    if(current_minute != last_label_update)
    {
        last_label_update = current_minute;
        UpdateChartLabels();
    }
    
    // 更新信号缓存状态（检查过期）
    UpdateSignalCache();
    
    // 检查止损条件
    CheckStopLoss();
    
    // 检查止盈条件（移除详细日志）
    CheckTakeProfitSimple();
    
    // 检查入场和加仓信号（使用新的缓存逻辑）
    CheckEntrySignalsWithCache();
}

//+------------------------------------------------------------------+
//| 交易事件处理函数                                                 |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
{
    // 只处理成交事件
    if(trans.type == TRADE_TRANSACTION_DEAL_ADD)
    {
        // 获取成交信息
        ulong dealTicket = trans.deal;
        if(HistoryDealSelect(dealTicket))
        {
            ENUM_DEAL_ENTRY dealEntry = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(dealTicket, DEAL_ENTRY);
            ENUM_DEAL_TYPE dealType = (ENUM_DEAL_TYPE)HistoryDealGetInteger(dealTicket, DEAL_TYPE);
            ulong orderTicket = HistoryDealGetInteger(dealTicket, DEAL_ORDER);
            ulong positionId = HistoryDealGetInteger(dealTicket, DEAL_POSITION_ID);
            
            // 只处理出场成交（平仓）
            if(dealEntry == DEAL_ENTRY_OUT)
            {
                Print("🔔 [成交事件] 检测到平仓成交 - 订单:", orderTicket, " 持仓ID:", positionId);
                
                // 检查是否还有同方向的持仓
                bool hasRemainingBuyPositions = false;
                bool hasRemainingSellPositions = false;
                
                for(int i = 0; i < PositionsTotal(); i++)
                {
                    if(m_position.SelectByIndex(i) && 
                       m_position.Symbol() == _Symbol && 
                       m_position.Magic() == InpMagic_Number)
                    {
                        if(m_position.PositionType() == POSITION_TYPE_BUY)
                            hasRemainingBuyPositions = true;
                        else if(m_position.PositionType() == POSITION_TYPE_SELL)
                            hasRemainingSellPositions = true;
                    }
                }
                
                // 如果没有剩余买单，重置多头移动止损状态
                if(!hasRemainingBuyPositions && g_state.trailing_active_buy)
                {
                    Print("🔄 [移动止损重置] 多头持仓已全部平仓，重置移动止损状态");
                    g_state.trailing_active_buy = false;
                    g_state.trailing_stop_buy = 0;
                }
                
                // 如果没有剩余卖单，重置空头移动止损状态
                if(!hasRemainingSellPositions && g_state.trailing_active_sell)
                {
                    Print("🔄 [移动止损重置] 空头持仓已全部平仓，重置移动止损状态");
                    g_state.trailing_active_sell = false;
                    g_state.trailing_stop_sell = 0;
                }
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 初始化交易状态                                                   |
//+------------------------------------------------------------------+
void InitTradingState()
{
    g_state.order_count = 0;
    g_state.last_buy_price = 0;
    g_state.last_sell_price = 0;
    g_state.lowest_buy_price = 0;
    g_state.highest_sell_price = 0;
    g_state.avg_buy_price = 0;
    g_state.avg_sell_price = 0;
    g_state.total_buy_lots = 0;
    g_state.total_sell_lots = 0;
    g_state.has_buy_positions = false;
    g_state.has_sell_positions = false;
    g_state.last_trade_time = 0;
    

    
    // 重置移动止损
    g_state.trailing_stop_buy = 0;
    g_state.trailing_stop_sell = 0;
    g_state.trailing_active_buy = false;
    g_state.trailing_active_sell = false;
}

//+------------------------------------------------------------------+
//| 更新交易状态                                                     |
//+------------------------------------------------------------------+
void UpdateTradingState()
{
    g_state.order_count = 0;
    g_state.total_buy_lots = 0;
    g_state.total_sell_lots = 0;
    g_state.has_buy_positions = false;
    g_state.has_sell_positions = false;
    
    double total_buy_value = 0;
    double total_sell_value = 0;
    g_state.lowest_buy_price = 0;
    g_state.highest_sell_price = 0;
    
    // 遍历所有持仓
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(m_position.SelectByIndex(i) && 
           m_position.Symbol() == _Symbol && 
           m_position.Magic() == InpMagic_Number)
        {
            g_state.order_count++;
            
            if(m_position.PositionType() == POSITION_TYPE_BUY)
            {
                g_state.has_buy_positions = true;
                double lot = m_position.Volume();
                double price = m_position.PriceOpen();
                
                g_state.total_buy_lots += lot;
                total_buy_value += lot * price;
                g_state.last_buy_price = price;
                
                if(g_state.lowest_buy_price == 0 || price < g_state.lowest_buy_price)
                    g_state.lowest_buy_price = price;
            }
            else if(m_position.PositionType() == POSITION_TYPE_SELL)
            {
                g_state.has_sell_positions = true;
                double lot = m_position.Volume();
                double price = m_position.PriceOpen();
                
                g_state.total_sell_lots += lot;
                total_sell_value += lot * price;
                g_state.last_sell_price = price;
                
                if(g_state.highest_sell_price == 0 || price > g_state.highest_sell_price)
                    g_state.highest_sell_price = price;
            }
        }
    }
    
    // 计算均价
    if(g_state.total_buy_lots > 0)
        g_state.avg_buy_price = total_buy_value / g_state.total_buy_lots;
    if(g_state.total_sell_lots > 0)
        g_state.avg_sell_price = total_sell_value / g_state.total_sell_lots;
}

//+------------------------------------------------------------------+
//| 更新RSI值                                                        |
//+------------------------------------------------------------------+
bool UpdateRSIValues()
{
    double rsi_buffer[3];
    if(CopyBuffer(h_RSI, 0, 0, 3, rsi_buffer) < 3)
    {
        Print("获取RSI数据失败");
        return false;
    }
    
    g_prev_rsi = rsi_buffer[1];
    g_curr_rsi = rsi_buffer[0];
    
    return true;
}

//+------------------------------------------------------------------+
//| 更新KDJ值                                                        |
//+------------------------------------------------------------------+
bool UpdateKDJValues()
{
    double k_buffer[3], d_buffer[3];
    if(CopyBuffer(h_Stochastic, 0, 0, 3, k_buffer) < 3 ||
       CopyBuffer(h_Stochastic, 1, 0, 3, d_buffer) < 3)
    {
        Print("获取KDJ数据失败");
        return false;
    }
    
    g_prev_k = k_buffer[1];
    g_curr_k = k_buffer[0];
    g_prev_d = d_buffer[1];
    g_curr_d = d_buffer[0];
    
    return true;
}

//+------------------------------------------------------------------+
//| 检查买入信号（只在低位区域检测金叉，RSI作为参考）                 |
//+------------------------------------------------------------------+
bool CheckBuySignal()
{
    // 放宽低位区域条件，增加交易机会
    bool kdj_in_low_area = (g_curr_k < 20.0 && g_curr_d < 30.0);
    
    if(!kdj_in_low_area) return false;  // 不在低位区域，直接返回false
    
    // 在低位区域才检测金叉
    bool kdj_golden_cross = (g_prev_k <= g_prev_d && g_curr_k > g_curr_d);
    
    // RSI作为参考指标，不是开单条件
    bool rsi_upward = InpUse_RSI_Trend ? (g_curr_rsi > g_prev_rsi) : true;
    
    return kdj_golden_cross && rsi_upward;
}

//+------------------------------------------------------------------+
//| 检查卖出信号（只在高位区域检测死叉，RSI作为参考）                 |
//+------------------------------------------------------------------+
bool CheckSellSignal()
{
    // 放宽高位区域条件，增加交易机会
    bool kdj_in_high_area = (g_curr_k > 80.0 && g_curr_d > 70.0);
    
    if(!kdj_in_high_area) return false;  // 不在高位区域，直接返回false
    
    // 在高位区域才检测死叉
    bool kdj_death_cross = (g_prev_k >= g_prev_d && g_curr_k < g_curr_d);
    
    // RSI作为参考指标，不是开单条件
    bool rsi_downward = InpUse_RSI_Trend ? (g_curr_rsi < g_prev_rsi) : true;
    
    return kdj_death_cross && rsi_downward;
}

//+------------------------------------------------------------------+
//| 检查入场信号（重构简化版）                                       |
//+------------------------------------------------------------------+
void CheckEntrySignals()
{
    double atr_value = GetATRValue();
    if(atr_value <= 0) return;

    // 检查买入信号
    bool buy_signal = CheckBuySignal();
    bool sell_signal = CheckSellSignal();
    
    // 买入逻辑
    if(buy_signal)
    {
        if(!g_state.has_buy_positions)
        {
            // 首次开仓
            Print("🎯 [开仓信号] RSI回升+KDJ金叉双重确认，执行买入开仓");
            double start_lot = NormalizeLot(InpStart_Lot);
            OpenPosition(ORDER_TYPE_BUY, start_lot);
            
            // 开仓成功后释放标记
            g_signal_cache.rsi_buy_rise = false;
            g_signal_cache.kdj_golden_cross = false;
            Print("✅ [信号释放] 开仓成功，释放RSI回升和KDJ金叉标记");
        }
        else if(g_state.order_count < InpMax_Orders)
        {
            // 加仓逻辑
            double ask_price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
            double required_distance = atr_value * InpATR_Distance;
            double actual_distance = ask_price - g_state.last_buy_price;
            
            if(actual_distance >= required_distance)
            {
                Print("🎯 [加仓信号] RSI回升+KDJ金叉双重确认，执行买入加仓");
                double next_lot = InpStart_Lot * MathPow(InpLot_Multiplier, g_state.order_count);
                next_lot = NormalizeLot(next_lot);
                OpenPosition(ORDER_TYPE_BUY, next_lot);
                
                // 加仓成功后释放标记
                g_signal_cache.rsi_buy_rise = false;
                g_signal_cache.kdj_golden_cross = false;
                Print("✅ [信号释放] 加仓成功，释放RSI回升和KDJ金叉标记");
            }
            else
            {
                Print("⏳ [加仓等待] 双重信号已确认，等待价格满足ATR距离要求");
            }
        }
    }
    
    // 卖出逻辑
    if(sell_signal)
    {
        if(!g_state.has_sell_positions)
        {
            // 首次开仓
            Print("🎯 [开仓信号] RSI回落+KDJ死叉双重确认，执行卖出开仓");
            double start_lot = NormalizeLot(InpStart_Lot);
            OpenPosition(ORDER_TYPE_SELL, start_lot);
            
            // 开仓成功后释放标记
            g_signal_cache.rsi_sell_fallback = false;
            g_signal_cache.kdj_death_cross = false;
            Print("✅ [信号释放] 开仓成功，释放RSI回落和KDJ死叉标记");
        }
        else if(g_state.order_count < InpMax_Orders)
        {
            // 加仓逻辑
            double bid_price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
            double required_distance = atr_value * InpATR_Distance;
            double actual_distance = bid_price - g_state.last_sell_price;
            
            if(actual_distance >= required_distance)
            {
                Print("🎯 [加仓信号] RSI回落+KDJ死叉双重确认，执行卖出加仓");
                double next_lot = InpStart_Lot * MathPow(InpLot_Multiplier, g_state.order_count);
                next_lot = NormalizeLot(next_lot);
                OpenPosition(ORDER_TYPE_SELL, next_lot);
                
                // 加仓成功后释放标记
                g_signal_cache.rsi_sell_fallback = false;
                g_signal_cache.kdj_death_cross = false;
                Print("✅ [信号释放] 加仓成功，释放RSI回落和KDJ死叉标记");
            }
            else
            {
                Print("⏳ [加仓等待] 双重信号已确认，等待价格满足ATR距离要求");
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 开仓函数                                                         |
//+------------------------------------------------------------------+
bool OpenPosition(ENUM_ORDER_TYPE order_type, double lot)
{
    // 规范化手数
    lot = NormalizeLot(lot);
    
    double price = (order_type == ORDER_TYPE_BUY) ? 
                   SymbolInfoDouble(_Symbol, SYMBOL_ASK) : 
                   SymbolInfoDouble(_Symbol, SYMBOL_BID);
    
    // 验证手数有效性
    double min_lot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
    double max_lot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
    
    if(lot < min_lot)
    {
        Print("手数过小：", lot, " 最小手数：", min_lot);
        return false;
    }
    
    if(lot > max_lot)
    {
        Print("手数过大：", lot, " 最大手数：", max_lot);
        return false;
    }
    
    bool result = false;
    if(order_type == ORDER_TYPE_BUY)
    {
        result = m_trade.Buy(lot, _Symbol, price, 0, 0, InpComment);
    }
    else
    {
        result = m_trade.Sell(lot, _Symbol, price, 0, 0, InpComment);
    }
    
    if(result)
    {
        Print("开仓成功：", EnumToString(order_type), " 手数：", lot, " 价格：", price);
        g_state.last_trade_time = TimeCurrent();
    }
    else
    {
        Print("开仓失败：", m_trade.ResultRetcode(), " - ", m_trade.ResultRetcodeDescription());
    }
    
    return result;
}

//+------------------------------------------------------------------+
//| 检查止盈条件                                                     |
//+------------------------------------------------------------------+
void CheckTakeProfit()
{
    if(!g_state.has_buy_positions && !g_state.has_sell_positions) return;
    
    double current_price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
    double atr_value = GetATRValue();
    if(atr_value <= 0) return;
    
    bool should_close = false;
    
    // 移动止损逻辑
    if(InpUse_Trailing_Stop)
    {
        UpdateTrailingStop(atr_value);
        // 移动止损通过订单修改实现，不需要手动平仓
    }
    
    // 方式1：固定止盈 - ATR倍数（保留作为备用）
    if(g_state.has_buy_positions && !InpUse_Trailing_Stop)
    {
        double tp_price = g_state.avg_buy_price + atr_value * InpATR_TP_Multi;
        if(current_price >= tp_price)
        {
            should_close = true;
            Print("固定止盈触发 - 买单，当前价格：", current_price, " 止盈价格：", tp_price);
        }
    }
    
    if(g_state.has_sell_positions && !InpUse_Trailing_Stop)
    {
        double tp_price = g_state.avg_sell_price - atr_value * InpATR_TP_Multi;
        if(current_price <= tp_price)
        {
            should_close = true;
            Print("固定止盈触发 - 卖单，当前价格：", current_price, " 止盈价格：", tp_price);
        }
    }
    
    // 方式2：RSI止盈（使用可调参数）
    if(InpUse_RSI_Exit && !should_close)
    {
        if(g_state.has_buy_positions && g_prev_rsi >= InpRSI_Upper && g_curr_rsi < InpRSI_Upper)
        {
            should_close = true;
            Print("RSI止盈触发 - 买单，RSI从", g_prev_rsi, "下穿至", g_curr_rsi);
        }
        
        if(g_state.has_sell_positions && g_prev_rsi <= InpRSI_Lower && g_curr_rsi > InpRSI_Lower)
        {
            should_close = true;
            Print("RSI止盈触发 - 卖单，RSI从", g_prev_rsi, "上穿至", g_curr_rsi);
        }
    }
    
    if(should_close)
    {
        CloseAllPositions();
    }
}

//+------------------------------------------------------------------+
//| 检查止损条件                                                     |
//+------------------------------------------------------------------+
void CheckStopLoss()
{
    if(!g_state.has_buy_positions && !g_state.has_sell_positions) return;
    
    // 条件1：检查总浮亏
    double total_profit = GetTotalProfit();
    if(total_profit <= -InpMax_Loss)
    {
        Print("最大亏损止损触发，亏损：", total_profit);
        CloseAllPositions();
        return;
    }
    
    // 条件2：第5单后的ATR止损
    if(g_state.order_count >= InpMax_Orders)
    {
        double current_price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
        double atr_value = GetATRValue();
        
        if(g_state.has_buy_positions && atr_value > 0)
        {
            double stop_price = g_state.lowest_buy_price - atr_value * InpATR_SL_Multi;
            if(current_price <= stop_price)
            {
                Print("ATR止损触发 - 买单，当前价格：", current_price, " 止损价格：", stop_price);
                CloseAllPositions();
                return;
            }
        }
        
        if(g_state.has_sell_positions && atr_value > 0)
        {
            double stop_price = g_state.highest_sell_price + atr_value * InpATR_SL_Multi;
            if(current_price >= stop_price)
            {
                Print("ATR止损触发 - 卖单，当前价格：", current_price, " 止损价格：", stop_price);
                CloseAllPositions();
                return;
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 平仓所有持仓                                                     |
//+------------------------------------------------------------------+
void CloseAllPositions()
{
    for(int i = PositionsTotal() - 1; i >= 0; i--)
    {
        if(m_position.SelectByIndex(i) && 
           m_position.Symbol() == _Symbol && 
           m_position.Magic() == InpMagic_Number)
        {
            m_trade.PositionClose(m_position.Ticket());
        }
    }
    
    // 重置状态
    InitTradingState();
    Print("所有持仓已平仓，策略状态已重置");
}

//+------------------------------------------------------------------+
//| 获取总盈亏                                                       |
//+------------------------------------------------------------------+
double GetTotalProfit()
{
    double total_profit = 0;
    
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(m_position.SelectByIndex(i) && 
           m_position.Symbol() == _Symbol && 
           m_position.Magic() == InpMagic_Number)
        {
            total_profit += m_position.Profit() + m_position.Swap() + m_position.Commission();
        }
    }
    
    return total_profit;
}

//+------------------------------------------------------------------+
//| 获取ATR值                                                        |
//+------------------------------------------------------------------+
double GetATRValue()
{
    double atr_buffer[1];
    if(CopyBuffer(h_ATR, 0, 1, 1, atr_buffer) < 1)
    {
        Print("获取ATR数据失败");
        return 0;
    }
    
    return atr_buffer[0];
}

//+------------------------------------------------------------------+
//| 手数规范化函数                                                   |
//+------------------------------------------------------------------+
double NormalizeLot(double lot)
{
    double min_lot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
    double max_lot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
    double lot_step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
    
    // 规范化到两位小数
    lot = NormalizeDouble(lot, 2);
    
    // 确保符合最小步长
    if(lot_step > 0)
    {
        lot = NormalizeDouble(MathRound(lot / lot_step) * lot_step, 2);
    }
    
    // 限制在允许范围内
    if(lot < min_lot) lot = min_lot;
    if(lot > max_lot) lot = max_lot;
    
    return NormalizeDouble(lot, 2);
}

//+------------------------------------------------------------------+
//| 更新移动止损                                                     |
//+------------------------------------------------------------------+
bool UpdateTrailingStop(double atr_value)
{
    // 多头移动止损
    if(g_state.has_buy_positions)
    {
        double bid_price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
        double trigger_distance = atr_value * InpTrail_Start_ATR;
        double profit_distance = bid_price - g_state.avg_buy_price;
        
        Print("🔍 [多头移动止损检查] 当前价格:", bid_price, " 均价:", g_state.avg_buy_price);
        Print("   📏 触发距离:", trigger_distance, " 当前盈利:", profit_distance);
        Print("   🎯 移动止损状态: 激活=", g_state.trailing_active_buy, " 当前止损=", g_state.trailing_stop_buy);
        
        // 检查是否达到启动移动止损的条件：价格高于买入均价+2倍ATR
        if(profit_distance >= trigger_distance)
        {
            double new_stop_loss = bid_price - atr_value * InpTrail_Distance_ATR;
            
            if(!g_state.trailing_active_buy)
            {
                // 首次激活移动止损
                g_state.trailing_stop_buy = new_stop_loss;
                g_state.trailing_active_buy = true;
                Print("✅ 多头移动止损激活 - 当前价格：", bid_price, " 止损价：", new_stop_loss);
                
                // 给所有多头订单设置止损
                SetStopLossForPositions(POSITION_TYPE_BUY, new_stop_loss);
            }
            else
            {
                // 更新移动止损（只能向上移动）
                double min_move = atr_value * InpTrail_Step_ATR;
                Print("   🔄 检查更新: 新止损=", new_stop_loss, " 当前止损=", g_state.trailing_stop_buy, " 最小移动=", min_move);
                
                if(new_stop_loss > g_state.trailing_stop_buy + min_move)
                {
                    g_state.trailing_stop_buy = new_stop_loss;
                    Print("✅ 多头移动止损更新 - 新止损价：", new_stop_loss);
                    
                    // 更新所有多头订单的止损
                    SetStopLossForPositions(POSITION_TYPE_BUY, new_stop_loss);
                }
                else
                {
                    Print("⏸️ 多头移动止损未更新 - 移动距离不足");
                }
            }
        }
        else
        {
            Print("⏳ 多头移动止损未激活 - 盈利距离不足");
        }
    }
    
    // 空头移动止损
    if(g_state.has_sell_positions)
    {
        double ask_price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
        double trigger_distance = atr_value * InpTrail_Start_ATR;
        double profit_distance = g_state.avg_sell_price - ask_price;
        
        Print("🔍 [空头移动止损检查] 当前价格:", ask_price, " 均价:", g_state.avg_sell_price);
        Print("   📏 触发距离:", trigger_distance, " 当前盈利:", profit_distance);
        Print("   🎯 移动止损状态: 激活=", g_state.trailing_active_sell, " 当前止损=", g_state.trailing_stop_sell);
        
        // 检查是否达到启动移动止损的条件：价格低于卖出均价-2倍ATR
        if(profit_distance >= trigger_distance)
        {
            double new_stop_loss = ask_price + atr_value * InpTrail_Distance_ATR;
            
            if(!g_state.trailing_active_sell)
            {
                // 首次激活移动止损
                g_state.trailing_stop_sell = new_stop_loss;
                g_state.trailing_active_sell = true;
                Print("✅ 空头移动止损激活 - 当前价格：", ask_price, " 止损价：", new_stop_loss);
                
                // 给所有空头订单设置止损
                SetStopLossForPositions(POSITION_TYPE_SELL, new_stop_loss);
            }
            else
            {
                // 更新移动止损（只能向下移动）
                double min_move = atr_value * InpTrail_Step_ATR;
                Print("   🔄 检查更新: 新止损=", new_stop_loss, " 当前止损=", g_state.trailing_stop_sell, " 最小移动=", min_move);
                
                if(new_stop_loss < g_state.trailing_stop_sell - min_move)
                {
                    g_state.trailing_stop_sell = new_stop_loss;
                    Print("✅ 空头移动止损更新 - 新止损价：", new_stop_loss);
                    
                    // 更新所有空头订单的止损
                    SetStopLossForPositions(POSITION_TYPE_SELL, new_stop_loss);
                }
                else
                {
                    Print("⏸️ 空头移动止损未更新 - 移动距离不足");
                }
            }
        }
        else
        {
            Print("⏳ 空头移动止损未激活 - 盈利距离不足");
        }
    }
    
    return false; // 不再手动平仓，由止损自动触发
}

//+------------------------------------------------------------------+
//| 为指定类型的持仓设置止损                                         |
//+------------------------------------------------------------------+
void SetStopLossForPositions(ENUM_POSITION_TYPE position_type, double stop_loss_price)
{
    double min_stop_level = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL) * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
    
    Print("🔧 [设置止损] 类型:", EnumToString(position_type), " 目标止损:", stop_loss_price, " 最小距离:", min_stop_level);
    
    int modified_count = 0;
    int skipped_count = 0;
    
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(m_position.SelectByIndex(i) && 
           m_position.Symbol() == _Symbol && 
           m_position.Magic() == InpMagic_Number &&
           m_position.PositionType() == position_type)
        {
            double current_price = (position_type == POSITION_TYPE_BUY) ? 
                                  SymbolInfoDouble(_Symbol, SYMBOL_BID) : 
                                  SymbolInfoDouble(_Symbol, SYMBOL_ASK);
            
            // 检查止损距离是否符合最小要求
            double stop_distance = (position_type == POSITION_TYPE_BUY) ? 
                                  current_price - stop_loss_price : 
                                  stop_loss_price - current_price;
            
            Print("   📊 订单", m_position.Ticket(), " 当前价格:", current_price, " 止损距离:", stop_distance);
            
            if(stop_distance >= min_stop_level)
            {
                double current_sl = m_position.StopLoss();
                double current_tp = m_position.TakeProfit();
                
                // 只有止损价格确实需要更新时才修改
                bool should_update = false;
                if(position_type == POSITION_TYPE_BUY)
                {
                    should_update = (current_sl == 0 || stop_loss_price > current_sl);
                }
                else
                {
                    should_update = (current_sl == 0 || stop_loss_price < current_sl);
                }
                
                Print("   🔍 订单", m_position.Ticket(), " 当前止损:", current_sl, " 需要更新:", should_update);
                
                if(should_update)
                {
                    if(m_trade.PositionModify(m_position.Ticket(), stop_loss_price, current_tp))
                    {
                        Print("✅ 订单", m_position.Ticket(), "止损更新成功：", stop_loss_price);
                        modified_count++;
                    }
                    else
                    {
                        Print("❌ 订单", m_position.Ticket(), "止损更新失败：", m_trade.ResultRetcode(), " - ", m_trade.ResultRetcodeDescription());
                    }
                }
                else
                {
                    Print("⏸️ 订单", m_position.Ticket(), "止损无需更新");
                    skipped_count++;
                }
            }
            else
            {
                Print("❌ 订单", m_position.Ticket(), "止损距离不足，要求：", min_stop_level, " 实际：", stop_distance);
            }
        }
    }
    
    Print("📈 [止损设置完成] 修改:", modified_count, " 跳过:", skipped_count);
}

//+------------------------------------------------------------------+
//| 初始化信号缓存                                                   |
//+------------------------------------------------------------------+
void InitSignalCache()
{
    g_signal_cache.rsi_buy_rise = false;
    g_signal_cache.rsi_sell_fallback = false;
    g_signal_cache.rsi_buy_expire_time = 0;
    g_signal_cache.rsi_sell_expire_time = 0;
    g_signal_cache.kdj_golden_cross = false;
    g_signal_cache.kdj_death_cross = false;
    g_signal_cache.kdj_golden_expire_time = 0;
    g_signal_cache.kdj_death_expire_time = 0;
    g_signal_cache.kdj_golden_last_update = 0;
    g_signal_cache.kdj_death_last_update = 0;
    g_signal_cache.kdj_low_entangle = false;
    g_signal_cache.kdj_high_entangle = false;
    g_signal_cache.kdj_low_entangle_ticks = 0;
    g_signal_cache.kdj_high_entangle_ticks = 0;
    g_signal_cache.kdj_low_entangle_start = 0;
    g_signal_cache.kdj_high_entangle_start = 0;
    g_signal_cache.signal_valid_bars = 5; // 固定为5根K线
}

//+------------------------------------------------------------------+
//| 检测RSI信号（每个tick都检查）                                     |
//+------------------------------------------------------------------+
void CheckRSISignalOnTick()
{
    datetime current_time = TimeCurrent();
    datetime expire_time = current_time + PeriodSeconds() * 5; // 固定5根K线
    
    // 获取当前K线的开盘RSI和当前tick的RSI
    double rsi_buffer[2];
    if(CopyBuffer(h_RSI, 0, 0, 2, rsi_buffer) < 2) return;
    
    double current_bar_open_rsi = rsi_buffer[1];  // 当前K线开盘时RSI
    double current_tick_rsi = rsi_buffer[0];      // 当前tick的RSI
    
    // 检测RSI回升：当前开盘价在买入阈值以下，当前tick等于买入阈值就视作RSI回升
    if(current_bar_open_rsi < InpRSI_Lower && current_tick_rsi >= InpRSI_Lower)
    {
        // 只有当前没有RSI回升信号时才设置新信号
        if(!g_signal_cache.rsi_buy_rise)
        {
            g_signal_cache.rsi_buy_rise = true;
            g_signal_cache.rsi_buy_expire_time = expire_time;
            Print("✅ [RSI回升] 买入信号触发 - 开盘RSI:", DoubleToString(current_bar_open_rsi, 1), 
                  " 当前RSI:", DoubleToString(current_tick_rsi, 1), 
                  " 阈值:", DoubleToString(InpRSI_Lower, 1),
                  " 过期时间:", TimeToString(expire_time, TIME_SECONDS));
        }
    }
    
    // 检测RSI回落：当前开盘价在卖出阈值以上，当前tick等于卖出阈值就视作RSI回落
    if(current_bar_open_rsi > InpRSI_Upper && current_tick_rsi <= InpRSI_Upper)
    {
        // 只有当前没有RSI回落信号时才设置新信号
        if(!g_signal_cache.rsi_sell_fallback)
        {
            g_signal_cache.rsi_sell_fallback = true;
            g_signal_cache.rsi_sell_expire_time = expire_time;
            Print("✅ [RSI回落] 卖出信号触发 - 开盘RSI:", DoubleToString(current_bar_open_rsi, 1), 
                  " 当前RSI:", DoubleToString(current_tick_rsi, 1), 
                  " 阈值:", DoubleToString(InpRSI_Upper, 1),
                  " 过期时间:", TimeToString(expire_time, TIME_SECONDS));
        }
    }
}

//+------------------------------------------------------------------+
//| 检测KDJ纠缠信号（每个tick都检查）                                  |
//+------------------------------------------------------------------+
void CheckKDJCrossSignalOnTick()
{
    datetime current_time = TimeCurrent();
    datetime expire_time = current_time + PeriodSeconds() * 5; // 固定5根K线
    
    // 计算K和D的差值
    double kd_diff = MathAbs(g_curr_k - g_curr_d);
    double entangle_threshold = 2.0; // 纠缠阈值：K和D差值小于2.0
    
    // 检测低位纠缠（K < 20）
    if(g_curr_k < 20.0)
    {
        if(kd_diff < entangle_threshold)
        {
            // 开始或继续低位纠缠
            if(!g_signal_cache.kdj_low_entangle)
            {
                // 开始新的纠缠
                g_signal_cache.kdj_low_entangle = true;
                g_signal_cache.kdj_low_entangle_ticks = 1;
                g_signal_cache.kdj_low_entangle_start = current_time;
                Print("🔄 [KDJ低位纠缠] 开始 - K:", DoubleToString(g_curr_k, 1), 
                      " D:", DoubleToString(g_curr_d, 1), " 差值:", DoubleToString(kd_diff, 1));
            }
            else
            {
                // 继续纠缠
                g_signal_cache.kdj_low_entangle_ticks++;
                
                // 纠缠持续2个tick以上，触发金叉信号
                if(g_signal_cache.kdj_low_entangle_ticks >= 2 && !g_signal_cache.kdj_golden_cross)
                {
                    g_signal_cache.kdj_golden_cross = true;
                    g_signal_cache.kdj_golden_expire_time = expire_time;
                    g_signal_cache.kdj_golden_last_update = current_time;
                    Print("✅ [KDJ金叉] 纠缠信号触发 - K:", DoubleToString(g_curr_k, 1), 
                          " D:", DoubleToString(g_curr_d, 1), " 纠缠tick数:", g_signal_cache.kdj_low_entangle_ticks,
                          " 过期时间:", TimeToString(expire_time, TIME_SECONDS));
                }
            }
        }
        else
        {
            // K和D分离，结束低位纠缠
            if(g_signal_cache.kdj_low_entangle)
            {
                Print("🔚 [KDJ低位纠缠] 结束 - K:", DoubleToString(g_curr_k, 1), 
                      " D:", DoubleToString(g_curr_d, 1), " 差值:", DoubleToString(kd_diff, 1),
                      " 持续tick数:", g_signal_cache.kdj_low_entangle_ticks);
                g_signal_cache.kdj_low_entangle = false;
                g_signal_cache.kdj_low_entangle_ticks = 0;
            }
        }
    }
    else
    {
        // K不在低位区域，结束低位纠缠
        if(g_signal_cache.kdj_low_entangle)
        {
            Print("🔚 [KDJ低位纠缠] 区域退出 - K:", DoubleToString(g_curr_k, 1), 
                  " D:", DoubleToString(g_curr_d, 1));
            g_signal_cache.kdj_low_entangle = false;
            g_signal_cache.kdj_low_entangle_ticks = 0;
        }
    }
    
    // 检测高位纠缠（K > 80）
    if(g_curr_k > 80.0)
    {
        if(kd_diff < entangle_threshold)
        {
            // 开始或继续高位纠缠
            if(!g_signal_cache.kdj_high_entangle)
            {
                // 开始新的纠缠
                g_signal_cache.kdj_high_entangle = true;
                g_signal_cache.kdj_high_entangle_ticks = 1;
                g_signal_cache.kdj_high_entangle_start = current_time;
                Print("🔄 [KDJ高位纠缠] 开始 - K:", DoubleToString(g_curr_k, 1), 
                      " D:", DoubleToString(g_curr_d, 1), " 差值:", DoubleToString(kd_diff, 1));
            }
            else
            {
                // 继续纠缠
                g_signal_cache.kdj_high_entangle_ticks++;
                
                // 纠缠持续2个tick以上，触发死叉信号
                if(g_signal_cache.kdj_high_entangle_ticks >= 2 && !g_signal_cache.kdj_death_cross)
                {
                    g_signal_cache.kdj_death_cross = true;
                    g_signal_cache.kdj_death_expire_time = expire_time;
                    g_signal_cache.kdj_death_last_update = current_time;
                    Print("✅ [KDJ死叉] 纠缠信号触发 - K:", DoubleToString(g_curr_k, 1), 
                          " D:", DoubleToString(g_curr_d, 1), " 纠缠tick数:", g_signal_cache.kdj_high_entangle_ticks,
                          " 过期时间:", TimeToString(expire_time, TIME_SECONDS));
                }
            }
        }
        else
        {
            // K和D分离，结束高位纠缠
            if(g_signal_cache.kdj_high_entangle)
            {
                Print("🔚 [KDJ高位纠缠] 结束 - K:", DoubleToString(g_curr_k, 1), 
                      " D:", DoubleToString(g_curr_d, 1), " 差值:", DoubleToString(kd_diff, 1),
                      " 持续tick数:", g_signal_cache.kdj_high_entangle_ticks);
                g_signal_cache.kdj_high_entangle = false;
                g_signal_cache.kdj_high_entangle_ticks = 0;
            }
        }
    }
    else
    {
        // K不在高位区域，结束高位纠缠
        if(g_signal_cache.kdj_high_entangle)
        {
            Print("🔚 [KDJ高位纠缠] 区域退出 - K:", DoubleToString(g_curr_k, 1), 
                  " D:", DoubleToString(g_curr_d, 1));
            g_signal_cache.kdj_high_entangle = false;
            g_signal_cache.kdj_high_entangle_ticks = 0;
        }
    }
    
    // 添加调试信息
    if(debug_counter % 100 == 0)
    {
        Print("🔍 [KDJ调试] 低位纠缠:", g_signal_cache.kdj_low_entangle, 
              " 高位纠缠:", g_signal_cache.kdj_high_entangle,
              " 低位tick数:", g_signal_cache.kdj_low_entangle_ticks,
              " 高位tick数:", g_signal_cache.kdj_high_entangle_ticks,
              " 已有金叉信号:", g_signal_cache.kdj_golden_cross,
              " 已有死叉信号:", g_signal_cache.kdj_death_cross);
    }
}

//+------------------------------------------------------------------+
//| 更新信号缓存状态                                                 |
//+------------------------------------------------------------------+
void UpdateSignalCache()
{
    datetime current_time = TimeCurrent();
    
    // 检查RSI信号是否过期
    if(g_signal_cache.rsi_buy_rise && current_time > g_signal_cache.rsi_buy_expire_time)
    {
        g_signal_cache.rsi_buy_rise = false;
        Print("⏰ [信号过期] RSI回升信号已过期");
    }
    
    if(g_signal_cache.rsi_sell_fallback && current_time > g_signal_cache.rsi_sell_expire_time)
    {
        g_signal_cache.rsi_sell_fallback = false;
        Print("⏰ [信号过期] RSI回落信号已过期");
    }
    
    // 检查KDJ信号是否过期
    if(g_signal_cache.kdj_golden_cross && current_time > g_signal_cache.kdj_golden_expire_time)
    {
        g_signal_cache.kdj_golden_cross = false;
        Print("⏰ [信号过期] KDJ金叉信号已过期");
    }
    
    if(g_signal_cache.kdj_death_cross && current_time > g_signal_cache.kdj_death_expire_time)
    {
        g_signal_cache.kdj_death_cross = false;
        Print("⏰ [信号过期] KDJ死叉信号已过期");
    }
}

//+------------------------------------------------------------------+
//| 更新图表标签                                                     |
//+------------------------------------------------------------------+
void UpdateChartLabels()
{
    if(!InpShow_Chart_Labels) return;
    
    // 删除旧标签
    ObjectDelete(0, "RSI_BUY_STATUS");
    ObjectDelete(0, "RSI_SELL_STATUS");
    ObjectDelete(0, "KDJ_GOLDEN_STATUS");
    ObjectDelete(0, "KDJ_DEATH_STATUS");
    ObjectDelete(0, "KDJ_LOW_ENTANGLE");
    ObjectDelete(0, "KDJ_HIGH_ENTANGLE");
    
    datetime current_time = TimeCurrent();
    int line_height = 20; // 每行间距
    int start_y = 30;     // 起始Y坐标
    
    // 显示RSI回升信号状态
    string rsi_buy_text = "RSI回升: " + (g_signal_cache.rsi_buy_rise ? "true" : "false");
    if(g_signal_cache.rsi_buy_rise)
    {
        int remaining_time = (int)((g_signal_cache.rsi_buy_expire_time - current_time) / PeriodSeconds());
        rsi_buy_text += " 剩余:" + IntegerToString(remaining_time) + "根K线";
    }
    CreateCornerLabel("RSI_BUY_STATUS", rsi_buy_text, start_y, 
                      g_signal_cache.rsi_buy_rise ? clrGreen : clrGray);
    
    // 显示RSI回落信号状态
    string rsi_sell_text = "RSI回落: " + (g_signal_cache.rsi_sell_fallback ? "true" : "false");
    if(g_signal_cache.rsi_sell_fallback)
    {
        int remaining_time = (int)((g_signal_cache.rsi_sell_expire_time - current_time) / PeriodSeconds());
        rsi_sell_text += " 剩余:" + IntegerToString(remaining_time) + "根K线";
    }
    CreateCornerLabel("RSI_SELL_STATUS", rsi_sell_text, start_y + line_height, 
                      g_signal_cache.rsi_sell_fallback ? clrRed : clrGray);
    
    // 显示KDJ金叉信号状态
    string kdj_golden_text = "KDJ金叉: " + (g_signal_cache.kdj_golden_cross ? "true" : "false");
    if(g_signal_cache.kdj_golden_cross)
    {
        int remaining_time = (int)((g_signal_cache.kdj_golden_expire_time - current_time) / PeriodSeconds());
        kdj_golden_text += " 剩余:" + IntegerToString(remaining_time) + "根K线";
    }
    CreateCornerLabel("KDJ_GOLDEN_STATUS", kdj_golden_text, start_y + line_height * 2, 
                      g_signal_cache.kdj_golden_cross ? clrGreen : clrGray);
    
    // 显示KDJ死叉信号状态
    string kdj_death_text = "KDJ死叉: " + (g_signal_cache.kdj_death_cross ? "true" : "false");
    if(g_signal_cache.kdj_death_cross)
    {
        int remaining_time = (int)((g_signal_cache.kdj_death_expire_time - current_time) / PeriodSeconds());
        kdj_death_text += " 剩余:" + IntegerToString(remaining_time) + "根K线";
    }
    CreateCornerLabel("KDJ_DEATH_STATUS", kdj_death_text, start_y + line_height * 3, 
                      g_signal_cache.kdj_death_cross ? clrOrange : clrGray);
    
    // 显示KDJ低位纠缠状态
    string kdj_low_entangle_text = "KDJ低位纠缠: " + (g_signal_cache.kdj_low_entangle ? "true" : "false");
    if(g_signal_cache.kdj_low_entangle)
    {
        kdj_low_entangle_text += " tick数:" + IntegerToString(g_signal_cache.kdj_low_entangle_ticks);
    }
    CreateCornerLabel("KDJ_LOW_ENTANGLE", kdj_low_entangle_text, start_y + line_height * 4, 
                      g_signal_cache.kdj_low_entangle ? clrBlue : clrGray);
    
    // 显示KDJ高位纠缠状态
    string kdj_high_entangle_text = "KDJ高位纠缠: " + (g_signal_cache.kdj_high_entangle ? "true" : "false");
    if(g_signal_cache.kdj_high_entangle)
    {
        kdj_high_entangle_text += " tick数:" + IntegerToString(g_signal_cache.kdj_high_entangle_ticks);
    }
    CreateCornerLabel("KDJ_HIGH_ENTANGLE", kdj_high_entangle_text, start_y + line_height * 5, 
                      g_signal_cache.kdj_high_entangle ? clrPurple : clrGray);
}

//+------------------------------------------------------------------+
//| 创建右上角标签                                                   |
//+------------------------------------------------------------------+
void CreateCornerLabel(string name, string text, int y_offset, color clr)
{
    if(!InpShow_Chart_Labels) return;
    
    ObjectDelete(0, name);
    ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
    ObjectSetString(0, name, OBJPROP_TEXT, text);
    ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
    ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 10);
    ObjectSetString(0, name, OBJPROP_FONT, "Arial Bold");
    ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_RIGHT_UPPER); // 右上角
    ObjectSetInteger(0, name, OBJPROP_XDISTANCE, 10);              // 距离右边距
    ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y_offset);        // Y坐标偏移
    ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_RIGHT_UPPER);
}

//+------------------------------------------------------------------+
//| 创建图表标签（保留原函数，但不再使用）                           |
//+------------------------------------------------------------------+
void CreateChartLabel(string name, string text, datetime time, double price, color clr)
{
    // 此函数已不再使用，保留以避免编译错误
}

//+------------------------------------------------------------------+
//| 简化的止盈检查（移除详细日志）                                   |
//+------------------------------------------------------------------+
void CheckTakeProfitSimple()
{
    if(!g_state.has_buy_positions && !g_state.has_sell_positions) return;
    
    double current_price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
    double atr_value = GetATRValue();
    if(atr_value <= 0) return;
    
    bool should_close = false;
    
    // 移动止损逻辑（无日志）
    if(InpUse_Trailing_Stop)
    {
        UpdateTrailingStopSimple(atr_value);
    }
    
    // 固定止盈检查（无日志）
    if(g_state.has_buy_positions && !InpUse_Trailing_Stop)
    {
        double tp_price = g_state.avg_buy_price + atr_value * InpATR_TP_Multi;
        if(current_price >= tp_price) should_close = true;
    }
    
    if(g_state.has_sell_positions && !InpUse_Trailing_Stop)
    {
        double tp_price = g_state.avg_sell_price - atr_value * InpATR_TP_Multi;
        if(current_price <= tp_price) should_close = true;
    }
    
    // RSI止盈检查（无日志）
    if(InpUse_RSI_Exit && !should_close)
    {
        if(g_state.has_buy_positions && g_prev_rsi >= InpRSI_Upper && g_curr_rsi < InpRSI_Upper)
            should_close = true;
        if(g_state.has_sell_positions && g_prev_rsi <= InpRSI_Lower && g_curr_rsi > InpRSI_Lower)
            should_close = true;
    }
    
    if(should_close)
    {
        CloseAllPositions();
    }
}

//+------------------------------------------------------------------+
//| 简化的移动止损更新（移除详细日志）                               |
//+------------------------------------------------------------------+
void UpdateTrailingStopSimple(double atr_value)
{
    // 多头移动止损
    if(g_state.has_buy_positions)
    {
        double bid_price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
        double trigger_distance = atr_value * InpTrail_Start_ATR;
        double profit_distance = bid_price - g_state.avg_buy_price;
        
        if(profit_distance >= trigger_distance)
        {
            double new_stop_loss = bid_price - atr_value * InpTrail_Distance_ATR;
            
            if(!g_state.trailing_active_buy)
            {
                g_state.trailing_stop_buy = new_stop_loss;
                g_state.trailing_active_buy = true;
                SetStopLossForPositionsSimple(POSITION_TYPE_BUY, new_stop_loss);
            }
            else
            {
                double min_move = atr_value * InpTrail_Step_ATR;
                if(new_stop_loss > g_state.trailing_stop_buy + min_move)
                {
                    g_state.trailing_stop_buy = new_stop_loss;
                    SetStopLossForPositionsSimple(POSITION_TYPE_BUY, new_stop_loss);
                }
            }
        }
    }
    
    //止损
    if(g_state.has_sell_positions)
    {
        double ask_price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
        double trigger_distance = atr_value * InpTrail_Start_ATR;
        double profit_distance = g_state.avg_sell_price - ask_price;
        
        if(profit_distance >= trigger_distance)
        {
            double new_stop_loss = ask_price + atr_value * InpTrail_Distance_ATR;
            
            if(!g_state.trailing_active_sell)
            {
                g_state.trailing_stop_sell = new_stop_loss;
                g_state.trailing_active_sell = true;
                SetStopLossForPositionsSimple(POSITION_TYPE_SELL, new_stop_loss);
            }
            else
            {
                double min_move = atr_value * InpTrail_Step_ATR;
                if(new_stop_loss < g_state.trailing_stop_sell - min_move)
                {
                    g_state.trailing_stop_sell = new_stop_loss;
                    SetStopLossForPositionsSimple(POSITION_TYPE_SELL, new_stop_loss);
                }
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 简化的止损设置（移除详细日志）                                   |
//+------------------------------------------------------------------+
void SetStopLossForPositionsSimple(ENUM_POSITION_TYPE position_type, double stop_loss_price)
{
    double min_stop_level = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL) * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
    
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(m_position.SelectByIndex(i) && 
           m_position.Symbol() == _Symbol && 
           m_position.Magic() == InpMagic_Number &&
           m_position.PositionType() == position_type)
        {
            double current_price = (position_type == POSITION_TYPE_BUY) ? 
                                  SymbolInfoDouble(_Symbol, SYMBOL_BID) : 
                                  SymbolInfoDouble(_Symbol, SYMBOL_ASK);
            
            double stop_distance = (position_type == POSITION_TYPE_BUY) ? 
                                  current_price - stop_loss_price : 
                                  stop_loss_price - current_price;
            
            if(stop_distance >= min_stop_level)
            {
                double current_sl = m_position.StopLoss();
                double current_tp = m_position.TakeProfit();
                
                bool should_update = false;
                if(position_type == POSITION_TYPE_BUY)
                    should_update = (current_sl == 0 || stop_loss_price > current_sl);
                else
                    should_update = (current_sl == 0 || stop_loss_price < current_sl);
                
                if(should_update)
                {
                    m_trade.PositionModify(m_position.Ticket(), stop_loss_price, current_tp);
                }
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 基于缓存的开仓信号检查                                           |
//+------------------------------------------------------------------+
void CheckEntrySignalsWithCache()
{
    double atr_value = GetATRValue();
    if(atr_value <= 0) return;

    // 检查买入信号：有RSI回升信号 且 有KDJ金叉信号
    bool buy_signal = (g_signal_cache.rsi_buy_rise && g_signal_cache.kdj_golden_cross);
    
    // 检查卖出信号：有RSI回落信号 且 有KDJ死叉信号
    bool sell_signal = (g_signal_cache.rsi_sell_fallback && g_signal_cache.kdj_death_cross);
    
    // 买入逻辑
    if(buy_signal)
    {
        if(!g_state.has_buy_positions)
        {
            // 首次开仓
            Print("🎯 [开仓信号] RSI回升+KDJ金叉双重确认，执行买入开仓");
            double start_lot = NormalizeLot(InpStart_Lot);
            OpenPosition(ORDER_TYPE_BUY, start_lot);
            
            // 开仓成功后释放标记
            g_signal_cache.rsi_buy_rise = false;
            g_signal_cache.kdj_golden_cross = false;
            Print("✅ [信号释放] 开仓成功，释放RSI回升和KDJ金叉标记");
        }
        else if(g_state.order_count < InpMax_Orders)
        {
            // 加仓逻辑
            double ask_price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
            double required_distance = atr_value * InpATR_Distance;
            double actual_distance = ask_price - g_state.last_buy_price;
            
            if(actual_distance >= required_distance)
            {
                Print("🎯 [加仓信号] RSI回升+KDJ金叉双重确认，执行买入加仓");
                double next_lot = InpStart_Lot * MathPow(InpLot_Multiplier, g_state.order_count);
                next_lot = NormalizeLot(next_lot);
                OpenPosition(ORDER_TYPE_BUY, next_lot);
                
                // 加仓成功后释放标记
                g_signal_cache.rsi_buy_rise = false;
                g_signal_cache.kdj_golden_cross = false;
                Print("✅ [信号释放] 加仓成功，释放RSI回升和KDJ金叉标记");
            }
            else
            {
                Print("⏳ [加仓等待] 双重信号已确认，等待价格满足ATR距离要求");
            }
        }
    }
    
    // 卖出逻辑
    if(sell_signal)
    {
        if(!g_state.has_sell_positions)
        {
            // 首次开仓
            Print("🎯 [开仓信号] RSI回落+KDJ死叉双重确认，执行卖出开仓");
            double start_lot = NormalizeLot(InpStart_Lot);
            OpenPosition(ORDER_TYPE_SELL, start_lot);
            
            // 开仓成功后释放标记
            g_signal_cache.rsi_sell_fallback = false;
            g_signal_cache.kdj_death_cross = false;
            Print("✅ [信号释放] 开仓成功，释放RSI回落和KDJ死叉标记");
        }
        else if(g_state.order_count < InpMax_Orders)
        {
            // 加仓逻辑
            double bid_price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
            double required_distance = atr_value * InpATR_Distance;
            double actual_distance = bid_price - g_state.last_sell_price;
            
            if(actual_distance >= required_distance)
            {
                Print("🎯 [加仓信号] RSI回落+KDJ死叉双重确认，执行卖出加仓");
                double next_lot = InpStart_Lot * MathPow(InpLot_Multiplier, g_state.order_count);
                next_lot = NormalizeLot(next_lot);
                OpenPosition(ORDER_TYPE_SELL, next_lot);
                
                // 加仓成功后释放标记
                g_signal_cache.rsi_sell_fallback = false;
                g_signal_cache.kdj_death_cross = false;
                Print("✅ [信号释放] 加仓成功，释放RSI回落和KDJ死叉标记");
            }
            else
            {
                Print("⏳ [加仓等待] 双重信号已确认，等待价格满足ATR距离要求");
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 检测RSI回升和回落信号（基于完整K线）                               |
//+------------------------------------------------------------------+
void CheckRSISignal()
{
    // 此函数已废弃，保留以避免编译错误
} 